home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CUCD / Programming / OUI / eprop.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  22.4 KB  |  719 lines

  1. // $Id: eprop.cc 1.2 1997/07/14 04:19:32 dlorre Exp dlorre $
  2.  
  3. #include <exec/lists.h>
  4. #include <graphics/gfxmacros.h>
  5. #include <intuition/classes.h>
  6. #include <intuition/classusr.h>
  7. #include <intuition/gadgetclass.h>
  8. #include <intuition/imageclass.h>
  9. #include <intuition/cghooks.h>
  10. #include <intuition/icclass.h>
  11. #include <utility/tagitem.h>
  12. #include <utility/hooks.h>
  13. #include <libraries/gadtools.h>
  14. #include <mydebug.h>
  15.  
  16. #include "gadgets/eprop.h"
  17. #include "gadgets/eclass.h"
  18.  
  19. #include "gadgetlist.h"
  20. #include "screen.h"
  21. #include "window.h"
  22.  
  23. #include <proto/graphics.h>
  24. #include <proto/intuition.h>
  25. #include <proto/utility.h>
  26. #include <clib/alib_protos.h>
  27. #include <compiler.h>
  28.  
  29. extern "C" STDARGS ULONG HookEntry() ;
  30.  
  31. static Class *BOOPSIeprop ;
  32. static int InitEProp(void) ;
  33. static void FreeEProp(void) ;
  34.  
  35. // ========================================================================
  36. // =============================  EPROP CLASS =============================
  37. // ========================================================================
  38.  
  39.  
  40. eprop::eprop(gadgetlist *gl,
  41.              void (window::*func)(gadget *, unsigned long, unsigned short),
  42.              long top,
  43.              long view,
  44.              long total,
  45.              long freedom,
  46.              char style) : gadget(gl, func)
  47. {
  48. short gleft, gtop, gwidth, gheight ;
  49.  
  50.     InitEProp() ;
  51.  
  52.     gleft = gl->ng->ng_LeftEdge ;
  53.     gtop = gl->ng->ng_TopEdge ;
  54.     gwidth = gl->ng->ng_Width ;
  55.     gheight = gl->ng->ng_Height ;
  56.  
  57.     if (style & BOTTOMPROP)
  58.         gtop = short(-gtop) ;
  59.     if (style & RIGHTPROP)
  60.         gleft = short(-gleft) ;
  61.     if (style & WIDTHPROP)
  62.         gwidth = short(-gwidth) ;
  63.     if (style & HEIGHTPROP)
  64.         gheight = short(-gheight) ;
  65.  
  66.     gad = gl->gad = (Gadget *)NewObject(BOOPSIeprop, NULL,
  67.             GA_Top,             gtop,
  68.             GA_Left,            gleft,
  69.             GA_Width,           gwidth,
  70.             GA_Height,          gheight,
  71.             GA_ID,              id,
  72.  
  73.             (style & BOTTOMPROP)?GA_BottomBorder:TAG_IGNORE,TRUE,
  74.             (style & RIGHTPROP)?GA_RightBorder:TAG_IGNORE,  TRUE,
  75.             (style & BOTTOMPROP)?GA_RelBottom:TAG_IGNORE,   TRUE,
  76.             (style & RIGHTPROP)?GA_RelRight:TAG_IGNORE,     TRUE,
  77.             (style & WIDTHPROP)?GA_RelWidth:TAG_IGNORE,     TRUE,
  78.             (style & HEIGHTPROP)?GA_RelHeight:TAG_IGNORE,   TRUE,
  79.  
  80.             GA_Immediate,       TRUE,
  81.             GA_FollowMouse,     TRUE,
  82.             GA_RelVerify,       TRUE,
  83.  
  84.             GA_Previous,        gl->gad,
  85.             GA_UserData,        PGA_Top,
  86.  
  87.             ICA_TARGET,         ICTARGET_IDCMP,
  88.  
  89.             PGA_Top,            top,
  90.             PGA_Total,          total,
  91.             PGA_Visible,        view,
  92.             PGA_Freedom,        freedom,
  93.             EGA_window,         gl->win,
  94.             TAG_END) ;
  95. }
  96.  
  97. eprop::~eprop()
  98. {
  99.     DisposeObject(gad) ;
  100.     FreeEProp() ;
  101. }
  102.  
  103.  
  104. void eprop::set(long top, long view, long total)
  105. {
  106.     SetGadgetAttrs(gad, w, NULL,
  107.         (top != -1)?PGA_Top:TAG_IGNORE,         top,
  108.         (total != -1)?PGA_Total:TAG_IGNORE,     total,
  109.         (view != -1)?PGA_Visible:TAG_IGNORE,    view,
  110.         TAG_END) ;
  111. }
  112.  
  113. void eprop::action(unsigned long classe, unsigned short code)
  114. {
  115.     if (classe != IDCMP_GADGETDOWN) {
  116.         gadget::action(classe, code) ;
  117.     }
  118. }
  119.  
  120. // ========================================================================
  121. // =============================== EPROP ==================================
  122. // ========================================================================
  123.  
  124. struct PropINST {
  125.  
  126.     long    Top ;
  127.     long    Total ;
  128.     long    Visible ;
  129.  
  130.     long    KLeft ;         // knob coords
  131.     long    KTop ;
  132.     long    KRight ;
  133.     long    KBottom ;
  134.  
  135.     long    PropLeft ;      // prop coords
  136.     long    PropTop ;
  137.     long    PropWidth ;
  138.     long    PropHeight ;
  139.  
  140.     long    IncLeft ;       // inc button coords
  141.     long    IncTop ;
  142.  
  143.     long    DecLeft ;       // dec button coords
  144.     long    DecTop ;
  145.  
  146.     long    ButWidth ;
  147.     long    ButHeight ;
  148.  
  149.     long    DTop ;
  150.     long    PTop ;          // previous top
  151.  
  152.     long    Flags ;
  153.  
  154.     BOOL    KnobHit ;
  155.     BOOL    DecHit ;
  156.     BOOL    IncHit ;
  157.  
  158.     BOOL    Drawable ;      // ok to redraw
  159.  
  160.     BOOL    RedrawAll ;
  161.     BOOL    RedrawInc ;
  162.     BOOL    RedrawDec ;
  163.     BOOL    RedrawBody ;
  164.     WORD    Direction ;     // Knob move=1, Inc=2, Dec=3
  165.  
  166.     window  *win ;
  167.  
  168.     struct  Image *arrowInc ;
  169.     struct  Image *arrowDec ;
  170. } ;
  171.  
  172. static ULONG STDARGS dispatchEProp(Class *cl, Object *o, Msg msg);
  173.  
  174. static ULONG   RenderEProp(Class *, Gadget *, gpRender *) ;
  175.  
  176. static void NotifyTop(Class *, Object *, ULONG, long, gpInput *) ;
  177.  
  178. static void    SetLims(PropINST *inst, Gadget *g, GadgetInfo *gi) ;
  179.  
  180. static void    CheckTop(PropINST *inst) ;
  181.  
  182.  
  183. static unsigned short ditherData[2] = {0x5555,0xAAAA};
  184. static int EPropCnt = 0 ;
  185.  
  186. int InitEProp(void)
  187. {
  188.     if (EPropCnt) {
  189.         EPropCnt++ ;
  190.     }
  191.     else if (!(BOOPSIeprop = MakeClass(NULL, (UBYTE *)"gadgetclass", NULL,
  192.         sizeof(PropINST), 0))) {
  193.         EPropCnt = 0 ;
  194.     }
  195.     else {
  196.         BOOPSIeprop->cl_Dispatcher.h_Entry = (HOOKFUNC)HookEntry ;
  197.         BOOPSIeprop->cl_Dispatcher.h_SubEntry = (HOOKFUNC)dispatchEProp;
  198.         BOOPSIeprop->cl_Dispatcher.h_Data = NULL ;
  199.         EPropCnt = 1 ;
  200.     }
  201.     return EPropCnt ;
  202. }
  203.  
  204. void FreeEProp(void)
  205. {
  206.     EPropCnt-- ;
  207.     if (!EPropCnt) {
  208.         FreeClass(BOOPSIeprop) ;
  209.     }
  210. }
  211.  
  212.  
  213. ULONG SAVEDS STDARGS dispatchEProp(Class *cl,
  214.                            Object *o,
  215.                            Msg msg)
  216. {
  217. PropINST *inst ;
  218. ULONG retval = FALSE ;
  219. Object *object ;
  220.  
  221.     GETA4 ;
  222.     switch (msg->MethodID) {
  223.     case OM_NEW:
  224.         if (object = (Object *)DoSuperMethodA(cl, o, msg)) {
  225.             Gadget *g = (Gadget *)object ;
  226.             screen *s ;
  227.  
  228.             inst = (PropINST *)INST_DATA(cl, object) ;
  229.             inst->KnobHit = inst->DecHit = inst->IncHit = FALSE ;
  230.             inst->Top = (long)GetTagData(PGA_Top, 0, ((opSet *)msg)->ops_AttrList ) ;
  231.             inst->Total = (long)GetTagData(PGA_Total, 0, ((opSet *)msg)->ops_AttrList) ;
  232.             inst->Visible = (long)GetTagData(PGA_Visible, 0, ((opSet *)msg)->ops_AttrList) ;
  233.             inst->Flags = (long)GetTagData(PGA_Freedom, LORIENT_VERT, ((opSet *)msg)->ops_AttrList) ;
  234.             inst->win = (window *)GetTagData(EGA_window, NULL, ((opSet *)msg)->ops_AttrList) ;
  235.             inst->RedrawAll = TRUE ;
  236.  
  237.  
  238.             if (g->Flags & GFLG_RELRIGHT)
  239.                 g->LeftEdge = (short)GetTagData(GA_Left, g->LeftEdge, ((opSet *)msg)->ops_AttrList) ;
  240.             if (g->Flags & GFLG_RELHEIGHT)
  241.                 g->Height = (short)GetTagData(GA_Height, g->Height, ((opSet *)msg)->ops_AttrList) ;
  242.             if (g->Flags & GFLG_RELWIDTH)
  243.                 g->Width = (short)GetTagData(GA_Width, g->Width, ((opSet *)msg)->ops_AttrList) ;
  244.             if (g->Flags & GFLG_RELBOTTOM)
  245.                 g->TopEdge = (short)GetTagData(GA_Top, g->TopEdge, ((opSet *)msg)->ops_AttrList) ;
  246.  
  247.             s = inst->win->ws ;
  248.  
  249.             inst->arrowInc = (Image *)NewObject(NULL, (UBYTE *)"sysiclass",
  250.                 IA_Left,        0,
  251.                 IA_Top,         0,
  252.                 SYSIA_DrawInfo, s->drawinfo,
  253.                 SYSIA_Which,    (inst->Flags & LORIENT_VERT)?DOWNIMAGE:RIGHTIMAGE,
  254.                 SYSIA_Size,     (s->scr->ViewPort.Modes & HIRES)?SYSISIZE_MEDRES:SYSISIZE_LOWRES,
  255.                 TAG_DONE) ;
  256.  
  257.             inst->arrowDec = (Image *)NewObject(NULL, (UBYTE *)"sysiclass",
  258.                 IA_Left,        0,
  259.                 IA_Top,         0,
  260.                 SYSIA_DrawInfo, s->drawinfo,
  261.                 SYSIA_Which,    (inst->Flags & LORIENT_VERT)?UPIMAGE:LEFTIMAGE,
  262.                 SYSIA_Size,     (s->scr->ViewPort.Modes & HIRES)?SYSISIZE_MEDRES:SYSISIZE_LOWRES,
  263.                 TAG_DONE) ;
  264.  
  265.             inst->ButWidth = inst->arrowInc->Width ;
  266.             inst->ButHeight = inst->arrowInc->Height ;
  267.  
  268.             retval = (ULONG)object ;
  269.         }
  270.  
  271.         break ;
  272.     case OM_DISPOSE:
  273.         inst = (PropINST *)INST_DATA(cl, o) ;
  274.         DisposeObject(inst->arrowInc) ;
  275.         DisposeObject(inst->arrowDec) ;
  276.         retval = DoSuperMethodA(cl, o, msg) ;
  277.         break ;
  278.     case GM_HITTEST:
  279.         retval = DoSuperMethodA(cl, o, msg) ;
  280.         break ;
  281.     case GM_GOACTIVE:
  282.         {
  283.         gpInput *gpi = (gpInput *)msg ;
  284.         WORD mx = gpi->gpi_Mouse.X ;
  285.         WORD my = gpi->gpi_Mouse.Y ;
  286.             inst = (PropINST *)INST_DATA(cl, o) ;
  287.             if (gpi->gpi_IEvent) {
  288.                 ((Gadget *)o)->Flags |= GFLG_SELECTED ;
  289.                 inst->RedrawAll = FALSE ;
  290.                 if (((mx + inst->PropLeft) >= inst->KLeft) &&
  291.                     ((mx + inst->PropLeft) <= inst->KRight) &&
  292.                     ((my + inst->PropTop) >= inst->KTop) &&
  293.                     ((my + inst->PropTop) <= inst->KBottom)) {
  294.                         inst->KnobHit = TRUE ;
  295.                         inst->Direction = 1 ;
  296.                         if (inst->Flags & LORIENT_VERT) {
  297.                             inst->DTop = (my * inst->Total) / inst->PropHeight - inst->Top ;
  298.                         }
  299.                         else {
  300.                             inst->DTop = (mx * inst->Total) / inst->PropWidth - inst->Top ;
  301.                         }
  302.                 }
  303.                 else if ((inst->Flags & LORIENT_VERT) &&
  304.                         ((my + inst->PropTop) >= inst->IncTop) &&
  305.                         ((my + inst->PropTop) <= (inst->IncTop+inst->ButHeight))) {
  306.                         inst->IncHit = TRUE ;
  307.                         inst->RedrawInc = TRUE ;
  308.                         inst->Direction = 2 ;
  309.                 }
  310.                 else if ((inst->Flags & LORIENT_VERT) &&
  311.                         ((my + inst->PropTop) >= inst->DecTop) &&
  312.                         ((my + inst->PropTop) <= (inst->DecTop+inst->ButHeight))) {
  313.                         inst->DecHit = TRUE ;
  314.                         inst->RedrawDec = TRUE ;
  315.                         inst->Direction = 3 ;
  316.                 }
  317.                 else if ((inst->Flags & LORIENT_HORIZ) &&
  318.                         ((mx + inst->PropLeft) >= inst->IncLeft) &&
  319.                         ((mx + inst->PropLeft) <= (inst->IncLeft+inst->ButWidth))) {
  320.                         inst->IncHit = TRUE ;
  321.                         inst->RedrawInc = TRUE ;
  322.                         inst->Direction = 2 ;
  323.                 }
  324.                 else if ((inst->Flags & LORIENT_HORIZ) &&
  325.                         ((mx + inst->PropLeft) >= inst->DecLeft) &&
  326.                         ((mx + inst->PropLeft) <= (inst->DecLeft+inst->ButWidth))) {
  327.                         inst->DecHit = TRUE ;
  328.                         inst->RedrawDec = TRUE ;
  329.                         inst->Direction = 3 ;
  330.                 }
  331.                 else {
  332.                     inst->Direction = 0 ;
  333.                     if (inst->Flags & LORIENT_VERT)
  334.                         if ((my + inst->PropTop)<= inst->KTop)
  335.                             inst->Top -= inst->Visible ;
  336.                         else
  337.                             inst->Top += inst->Visible ;
  338.                     else
  339.                         if ((mx + inst->PropLeft)<= inst->KLeft)
  340.                             inst->Top -= inst->Visible ;
  341.                         else
  342.                             inst->Top += inst->Visible ;
  343.  
  344.                     CheckTop(inst) ;
  345.  
  346.                 }
  347.                 NotifyTop(cl, o, OPUF_INTERIM, inst->Top, gpi) ;
  348.                 retval = GMR_MEACTIVE ;
  349.                 *(gpi->gpi_Termination) = inst->Top ;
  350.                 RenderEProp(cl, (Gadget *)o, (gpRender *)msg) ;
  351.             }
  352.             else
  353.                 retval = GMR_NOREUSE ;
  354.         }
  355.         break ;
  356.  
  357.     case GM_RENDER:
  358.         retval = RenderEProp(cl, (Gadget *)o, (gpRender *)msg) ;
  359.         break ;
  360.     case GM_HANDLEINPUT:
  361.         {
  362.             gpInput *gpi = (gpInput *)msg ;
  363.             InputEvent *ie = gpi->gpi_IEvent ;
  364.             WORD mx = gpi->gpi_Mouse.X ;
  365.             WORD my = gpi->gpi_Mouse.Y ;
  366.  
  367.             inst = (PropINST *)INST_DATA(cl, o) ;
  368.             inst->PTop = inst->Top ;
  369.             retval = GMR_MEACTIVE  ;
  370.  
  371.             if (ie->ie_Class == IECLASS_RAWMOUSE) {
  372.                 switch (ie->ie_Code) {
  373.                     case SELECTUP:
  374.                         *(gpi->gpi_Termination) = inst->Top ;
  375.                         retval = GMR_NOREUSE | GMR_VERIFY ;
  376.                         break ;
  377.                     case MENUDOWN:
  378.                         retval = GMR_REUSE ;
  379.                         NotifyTop(cl, o, 0, inst->Top, (gpInput *)msg) ;
  380.                         break ;
  381.                     default:
  382.                         retval = GMR_MEACTIVE ;
  383.                 }
  384.             }
  385.             else if ((ie->ie_Class == IECLASS_TIMER ||
  386.                 ie->ie_Class == IECLASS_POINTERPOS)
  387.                 && inst->Direction) {
  388.                 switch (inst->Direction) {
  389.                 case 1:
  390.                     if (inst->Flags & LORIENT_VERT) {
  391.                         inst->Top = (my * inst->Total) / inst->PropHeight - inst->DTop ;
  392.                     }
  393.                     else {
  394.                         inst->Top = (mx * inst->Total) / inst->PropWidth - inst->DTop ;
  395.                     }
  396.                     break ;
  397.                 case 2:
  398.                     inst->Top++ ;
  399.                     break ;
  400.                 case 3:
  401.                     inst->Top-- ;
  402.                     break ;
  403.                 }
  404.                 CheckTop(inst) ;
  405.                 if (inst->PTop != inst->Top) {
  406.                     RenderEProp(cl, (Gadget *)o, (gpRender *)msg) ;
  407.                     inst->RedrawInc = inst->RedrawDec = FALSE ;
  408.                     NotifyTop(cl, o, OPUF_INTERIM, inst->Top, gpi) ;
  409.                 }
  410.             }
  411.         }
  412.         break ;
  413.     case GM_GOINACTIVE:
  414.         ((Gadget *)o)-> Flags &= ~GFLG_SELECTED ;
  415.         inst = (PropINST *)INST_DATA(cl, o) ;
  416.         inst->KnobHit = inst->IncHit = inst->DecHit = FALSE ;
  417.         inst->RedrawAll = TRUE ;
  418.         inst->RedrawInc = inst->RedrawDec = FALSE ;
  419.         inst->RedrawBody = FALSE ;
  420.         RenderEProp(cl, (Gadget *)o, (gpRender *)msg) ;
  421.         break ;
  422.     case OM_GET:
  423.         inst = (PropINST *)INST_DATA(cl, o) ;
  424.         switch (((opGet *)msg)->opg_AttrID) {
  425.         case PGA_Top:
  426.             retval = inst->Top ;
  427.             break ;
  428.         case PGA_Total:
  429.             retval = inst->Total ;
  430.             break ;
  431.         case PGA_Visible:
  432.             retval = inst->Visible ;
  433.             break ;
  434.         default:
  435.             retval = DoSuperMethodA(cl, o, msg) ;
  436.         }
  437.         break ;
  438.     case OM_SET:
  439.         if ( FindTagItem(PGA_Top, ((opSet *)msg)->ops_AttrList) ||
  440.             FindTagItem(PGA_Total, ((opSet *)msg)->ops_AttrList) ||
  441.             FindTagItem(PGA_Visible, ((opSet *)msg)->ops_AttrList) ) {
  442.             RastPort *rp ;
  443.             Gadget *g  = (Gadget *)o ;
  444.  
  445.             inst = (PropINST *)INST_DATA(cl, o) ;
  446.             inst->Top = (long)GetTagData(PGA_Top, inst->Top, ((opSet *)msg)->ops_AttrList) ;
  447.             inst->Total = (long)GetTagData(PGA_Total, inst->Total, ((opSet *)msg)->ops_AttrList) ;
  448.             inst->Visible = (long)GetTagData(PGA_Visible, inst->Visible, ((opSet *)msg)->ops_AttrList) ;
  449.  
  450.             CheckTop(inst) ;
  451.  
  452.             SetLims(inst, g, ((opSet *)msg)->ops_GInfo) ;
  453.             inst->RedrawAll = FALSE ;
  454.             inst->RedrawBody = TRUE ;
  455.  
  456.             if (rp = ObtainGIRPort( ((opSet *)msg)->ops_GInfo) ) {
  457.  
  458.                 DoMethod(o, GM_RENDER, ((opSet *)msg)->ops_GInfo, rp, GREDRAW_REDRAW) ;
  459.                 ReleaseGIRPort(rp) ;
  460.             }
  461.             inst->RedrawBody = FALSE ;
  462.             inst->RedrawAll = TRUE ;
  463.         }
  464.         else
  465.             retval = DoSuperMethodA(cl, o, msg) ;
  466.         break ;
  467.     default :
  468.         retval = DoSuperMethodA(cl, o, msg) ;
  469.         break ;
  470.     }
  471.     return retval ;
  472. }
  473.  
  474. void SAVEDS CheckTop(PropINST *inst)
  475. {
  476.     GETA4 ;
  477.     if (inst->Top < 0)
  478.         inst->Top = 0 ;
  479.     else if (inst->Visible <= inst->Total) {
  480.         if ((inst->Top + inst->Visible) > (inst->Total+1)) {
  481.             inst->Top = inst->Total - inst->Visible + 1 ;
  482.         }
  483.     }
  484.     else if (inst->Visible > inst->Total)
  485.         inst->Top = 0 ;
  486. //    else if (inst->Top >= inst->Total)
  487. //        inst->Top = inst->Total - 1 ;
  488. }
  489.  
  490. void SAVEDS NotifyTop(Class *cl, Object *o, ULONG flags, long top, gpInput *gpi)
  491. {
  492. static TagItem tt[3] ;
  493.  
  494.     GETA4 ;
  495.     tt[0].ti_Tag = PGA_Top ;
  496.     tt[0].ti_Data = top  ;
  497.  
  498.     tt[1].ti_Tag = GA_ID ;
  499.     tt[1].ti_Data = ((Gadget *)o)->GadgetID ;
  500.  
  501.     tt[2].ti_Tag = TAG_DONE ;
  502.  
  503.     DoSuperMethod(cl, o, OM_NOTIFY, tt, gpi->gpi_GInfo, flags) ;
  504. }
  505.  
  506. ULONG SAVEDS RenderEProp(Class *cl, Gadget *g, gpRender *msg)
  507. {
  508. RastPort *rp ;
  509. ULONG retval = TRUE ;
  510. UWORD *pens = msg->gpr_GInfo->gi_DrInfo->dri_Pens ;
  511. PropINST *inst = (PropINST *)INST_DATA(cl, (Object *)g) ;
  512.  
  513.     GETA4 ;
  514.     // Obtention du rastport
  515.  
  516.     if (msg->MethodID == GM_RENDER)
  517.         rp = msg->gpr_RPort ;
  518.     else
  519.         rp = ObtainGIRPort(msg->gpr_GInfo) ;
  520.  
  521.     if (rp) {
  522.         UWORD shine, shadow ;
  523.         long  flag ;
  524.  
  525.         SetAPen(rp, pens[SHADOWPEN]) ;
  526.         SetBPen(rp, 0) ;
  527.         SetDrMd(rp, JAM2) ;
  528.         SetAfPt(rp, ditherData, 1) ;
  529.  
  530.         // Redessiner tout ou bien tout sauf partie +/- ?
  531.  
  532.         if (inst->RedrawAll || inst->RedrawBody) {
  533.             SetLims(inst, g, msg->gpr_GInfo) ;  // Calcul des limites
  534.  
  535.             if (!inst->Drawable) {
  536.                 retval = FALSE ;
  537.                 goto out ;
  538.             }
  539.             RectFill(rp,            // Effacer tout le corps du Gadget
  540.                 inst->PropLeft,
  541.                 inst->PropTop,
  542.                 inst->PropLeft+inst->PropWidth-1,
  543.                 inst->PropTop+inst->PropHeight-1) ;
  544.         }
  545.         else {                      // Effacer le knob
  546.             RectFill(rp,
  547.                 inst->KLeft,
  548.                 inst->KTop,
  549.                 inst->KRight,
  550.                 inst->KBottom) ;
  551.             SetLims(inst, g, msg->gpr_GInfo) ;  // Calcul des limites
  552.             if (!inst->Drawable) {
  553.                 retval = FALSE ;
  554.                 goto out ;
  555.             }
  556.         }
  557.         SetAfPt(rp, NULL, 0 ) ; // Fin du tramage
  558.  
  559.         // Choix des pinceaux suivant activation du Knob
  560.         if (inst->KnobHit) {
  561.             shine = pens[SHADOWPEN] ;
  562.             shadow = pens[SHINEPEN] ;
  563.         }
  564.         else {
  565.             shine = pens[SHINEPEN] ;
  566.             shadow = pens[SHADOWPEN] ;
  567.         }
  568.  
  569.         SetAPen(rp, pens[HIGHLIGHTTEXTPEN]) ;    // Activer le tramage
  570.         SetAfPt(rp, ditherData, 1) ;
  571.  
  572.         RectFill(rp, inst->KLeft,     // Dessiner le Knob
  573.                      inst->KTop,
  574.                      inst->KRight,
  575.                      inst->KBottom) ;
  576.  
  577.         SetAfPt(rp, NULL, 0 ) ;         // Fin du tramage
  578.  
  579.         // Contours du knob
  580.  
  581.         SetAPen(rp, shadow) ;
  582.         Move(rp, inst->KLeft+1, inst->KBottom) ;
  583.         Draw(rp, inst->KRight, inst->KBottom) ;
  584.         Draw(rp, inst->KRight, inst->KTop+1) ;
  585.  
  586.         SetAPen(rp, shine) ;
  587.         Move(rp, inst->KLeft, inst->KBottom-1) ;
  588.         Draw(rp, inst->KLeft, inst->KTop) ;
  589.         Draw(rp, inst->KRight-1, inst->KTop) ;
  590.  
  591.         if (msg->gpr_GInfo->gi_Window->Flags & WFLG_WINDOWACTIVE) {
  592.             flag = 0 ;
  593.         }
  594.         else {
  595.             flag = IDS_INACTIVENORMAL ;
  596.         }
  597.  
  598.         // Partie [-]
  599.  
  600.         if (inst->RedrawDec || inst->RedrawAll) {
  601.             DrawImageState( rp, inst->arrowDec,
  602.                 inst->DecLeft, inst->DecTop,
  603.                 inst->DecHit?flag+IDS_SELECTED:flag+IDS_NORMAL, inst->win->ws->drawinfo);
  604.         }
  605.  
  606.         // Partie [+]
  607.  
  608.         if (inst->RedrawInc || inst->RedrawAll) {
  609.             DrawImageState( rp, inst->arrowInc,
  610.                 inst->IncLeft, inst->IncTop,
  611.                 inst->IncHit?flag+IDS_SELECTED:flag+IDS_NORMAL, inst->win->ws->drawinfo);
  612.  
  613.         }
  614.  
  615. out:
  616.         if (msg->MethodID != GM_RENDER) // Restitution du RastPort
  617.             ReleaseGIRPort(rp) ;
  618.     }
  619.     else
  620.         retval = FALSE ;
  621.     return retval ;
  622. }
  623.  
  624.  
  625. void SAVEDS SetLims(PropINST *inst, Gadget *g, GadgetInfo *gi)
  626. {
  627. long GLeft, GTop, GWidth, GHeight ;
  628. long KWidth, KHeight ;
  629.  
  630.     GETA4 ;
  631.     GLeft = g->LeftEdge ;
  632.     GTop = g->TopEdge ;
  633.     GWidth = g->Width  ;
  634.     GHeight = g->Height ;
  635.  
  636.     if (g->Flags & GFLG_RELRIGHT) {
  637.         GLeft = gi->gi_Window->Width ;
  638.         GLeft += g->LeftEdge ;
  639.     }
  640.  
  641.     if (g->Flags & GFLG_RELHEIGHT) {
  642.         GHeight = gi->gi_Window->Height ;
  643.         GHeight += g->Height ;
  644.     }
  645.  
  646.     if (g->Flags & GFLG_RELBOTTOM) {
  647.         GTop = gi->gi_Window->Height ;
  648.         GTop += g->TopEdge ;
  649.     }
  650.  
  651.     if (g->Flags & GFLG_RELWIDTH) {
  652.         GWidth = gi->gi_Window->Width ;
  653.         GWidth += g->Width ;
  654.     }
  655.  
  656.     if (g->Activation & GACT_BOTTOMBORDER) {
  657.         GTop-- ;
  658.     }
  659.     if (g->Activation & GACT_RIGHTBORDER) {
  660.         GLeft-- ;
  661.     }
  662.  
  663.     if (inst->Flags & LORIENT_VERT)
  664.         inst->Drawable = short((GWidth > 4) && (GHeight > inst->ButHeight*2+8) &&
  665.         (gi->gi_Window->Width > (GWidth+gi->gi_Window->BorderLeft))) ;
  666.     else
  667.         inst->Drawable = short((GWidth > inst->ButWidth*2+8) && (GHeight > 4) &&
  668.         (gi->gi_Window->Height > (GHeight+gi->gi_Window->BorderTop))) ;
  669.  
  670.     inst->PropLeft = GLeft  ;
  671.     inst->PropTop = GTop ;
  672.  
  673.     if (inst->Flags & LORIENT_VERT) {
  674.         inst->PropLeft += 2 ;
  675.         inst->PropWidth = GWidth  - 4 ;
  676.         inst->PropHeight = GHeight - inst->ButHeight*2 ;
  677.         inst->DecLeft = inst->IncLeft = GLeft ;
  678.         inst->DecTop = inst->PropTop + inst->PropHeight ;
  679.         inst->IncTop = inst->DecTop + inst->ButHeight ;
  680.     }
  681.     else {
  682.         inst->PropTop += 2 ;
  683.         inst->PropHeight = GHeight - 4 ;
  684.         inst->PropWidth = GWidth - inst->ButWidth*2 ;
  685.         inst->DecTop = inst->IncTop = GTop ;
  686.         inst->DecLeft = inst->PropLeft + inst->PropWidth ;
  687.         inst->IncLeft = inst->DecLeft + inst->ButWidth ;
  688.     }
  689.  
  690.     inst->KLeft = inst->PropLeft ;
  691.     inst->KTop = inst->PropTop ;
  692.     KWidth = inst->PropWidth  ;
  693.     KHeight = inst->PropHeight   ;
  694.  
  695.     if ((inst->Flags & LORIENT_HORIZ) && (inst->Total >= inst->Visible)) {
  696.         inst->KLeft += (inst->PropWidth * inst->Top) / (inst->Total+1) ;
  697.         KWidth *= inst->Visible ;
  698.         KWidth /= (inst->Total+1) ;
  699.         if (KWidth < 8) {
  700.             KWidth = 8 ;
  701.             if (inst->KLeft > (inst->DecLeft - 8))
  702.                 inst->KLeft = inst->DecLeft - 8 ;
  703.         }
  704.     }
  705.     else if ((inst->Flags & LORIENT_VERT) && (inst->Total >= inst->Visible)) {
  706.         inst->KTop += (inst->PropHeight * inst->Top) / (inst->Total+1) ;
  707.         KHeight *= inst->Visible ;
  708.         KHeight /= (inst->Total+1) ;
  709.         if (KHeight < 8) {
  710.             KHeight = 8 ;
  711.             if (inst->KTop > (inst->DecTop - 8))
  712.                 inst->KTop = inst->DecTop - 8 ;
  713.         }
  714.     }
  715.  
  716.     inst->KRight = inst->KLeft + KWidth -1;
  717.     inst->KBottom = inst->KTop + KHeight -1;
  718. }
  719.